package com.bytezreo.duotai2;

import java.sql.Date;

/**
 * 
 * @Description    面向对象的特征三 ------多态性
 * @author  Bytezero·zhenglei!      Email:420498246@qq.com
 * @version
 * @date 2021年9月20日下午4:56:10
 * @
 * 
 * 
 * 1.理解多态性：  可以理解为一个事物的多态性 
 * 2.何为多态性：  父类的引用指向子类的对象（或子类的对象赋给父类的引用）
 *
 * 3.多态的使用：虚拟方法调用
 * 有了对象的多态性的以后，我们在编译器期，只能调用父类中声明的方法，但是
 * 在运行期，我们实际执行的是 子类重写父类的方法。
 * 
 *  总结：编译，看左边，执行看右边
 *  
 * 4.多态性的使用前提：(1)类的继承关系  (2) 要有方法的重写
 *
 * 5.对象的多态性，适用于方法，不适用于属性(属性：编译和运行都只看左边)
 *
 * 6.多态性是运行时行为;        
 * 
 * 7.动态绑定
 * 
 * 
 * ****************************************************************************
 * 
 * 
 * 
 */
public class PersonTest 
{
	public static void main(String[] args) 
	{
		Person p1 = new Person();
		p1.eat();
		
		
		Man man = new Man();
		man.eat();
		man.age = 25;
		man.makeMoney();
		
		/***********************/
		System.out.println("----------------------------");
		//对象多态性：父类的引用指向子类的对象
		Person p2 = new Man();
		
		//多态的使用：当调用子父类同名同参的方法时，实际执行的是子类重写父类的
	//方法---虚拟方法调用
		p2.eat();    //子类的
		p2.walk();
		
		
		//p2.makeMoney();
		
		
		
		
//		Person p3 = new Woman();
		
		System.out.println(p2.id); //1001   父类
	//	***********************************************
		
		
		System.out.println("************************");
		
		
		//不能调用子类所特有的方法,属性：编译时，p2是person类型，
//		p2.makeMoney();
		
		//p2.isSmoking = true;
		p2.name = "Tom";
		
		//有了对象的多态性以后，内存中实际上是加载了子类特有的属性和方法，但是
//由于变量声明为父类类型，导致编译时，只能调用父类中声明的属性和方法。子类特有的
//属性和方法不能调用。
		
		//如何才能调用子类特有的属性和方法？
		//使用强制类型转换符 
		Man m1 =  (Man)p2; //强转类型
		m1.makeMoney();
		m1.isSmoking = true;
		
		
		//使用强转时，可能出现 .ClassCastException的异常
//		Woman w1 = (Woman)p2;
//		w1.goShopping();
		
		//为了避免 ClassCastException的异常 引入了
		// instanceof  全小写
		/**
		 *  instanceof  全小写 关键字使用
		 *  
		 *  a  instanceof A : 判断 对象 a 是否是类A的实例
		 *  如果是 返回 true  不是返回 false
		 *  
		 *  
		 *  使用情境：为了避免向下转型时出现 ClassCastException的异常，我们在向下
		 *  转型进行之前，先进行 instancof 的判断，一旦返沪true,就进行向下转型，
		 *  如果 返回 false，不进行向下转型
		 *  
		 *  如果 a instanceof A 返回 true,则 a instanceof B 也返回true.
		 *  其中 类B是类A的父类。
		 *  
		 *  
		 */
		
		//执行不了   new 的是什么就是什么  Person p2 = new Man();
		if(p2 instanceof Woman)
		{
			Woman w1 =(Woman)p2;
			w1.goShopping();
			System.out.println("******* Woman*****");
		}
		
		
		
		if(p2 instanceof Man)
		{
			Man m2 =(Man)p2;
			m2.makeMoney();
			System.out.println("******* Man*****");
		}
		
		if(p2 instanceof Person)
		{
			System.out.println(" ************  Person *********");
		}
		
		if(p2 instanceof Object)
		{
			System.out.println("---------- Object ----------");
		}
		
		
		
		
		//练习：
		//问题一：编译通过，运行不通过
		  //举例一
//        Person p3= new Woman();
//        Man m3 = (Man)p3;
		
		//举例二
//		Person p4 = new Person();   //不可以
//		Man m4 = (Man)p4;
	
		
		
		//问题二：编译通过  运行通过  父类的父类   Woman 子类
//		Object obj = new Woman();   //可以的
//		Person p = (Person)obj;
		
		
		//问题三  编译不通过
		
        // Man m5 =  new  Woman();  类型不匹配，没有任何关系，鄙必须是子父类
		
		//String str = new Date();
		
//		Object p = new Date();
//		String str1 = (String) p;
	}
}






















































